home *** CD-ROM | disk | FTP | other *** search
- Path: news.daimi.aau.dk!liborius
- From: liborius@daimi.aau.dk (Per Liboriussen)
- Newsgroups: comp.sys.amiga.programmer
- Subject: Re: 3 bugs in SAS/C v. 6.56
- Date: 1 Mar 1996 09:27:46 GMT
- Organization: DAIMI, Computer Science Dept. at Aarhus University
- Message-ID: <4h6fui$b1t@gjallar.daimi.aau.dk>
- References: <4gs3hk$7mp@gjallar.daimi.aau.dk> <4h0lvl$du2@newsserver.trl.OZ.AU>
- NNTP-Posting-Host: yen.daimi.aau.dk
-
- Thus spake aduncan@rhea.trl.OZ.AU (Allan Duncan):
-
- [ Original (slightly modified) code deleted]
-
- >> Anyway, when a compiler evaluates a boolean expression such as ">", it
- >> must perform the usual integral promotions. This means that types narrower
- >> than int are promoted to int before the comparison. Even in your example
- >> above the compiler must take the (integer) constant 0x7fff, convert it to
-
- > ^
- > unsigned for ANSI
-
- Not according to "The C Programming Language" by Kernighan and Ritchie
- (second edition). In Appendix A (the reference manual), section A2.5.1
- they say that an unsuffixed hexadecimal integer constant has the first
- possible of the following types: int, unsigned int, long int and unsigned
- long int.
-
-
- >Try this test programme (for a 32 bit int and 2's complement
- >arithmetic):
-
- >#include <stdio.h>
-
- >#define K 0xFFFFFFFF
-
- >main()
- >{
- >printf( "Int %d, long %d, short %d\n", sizeof( int ), sizeof( long int),
- > sizeof( short int ) ) ;
- >if ( K > 0 ) printf( "ANSI C\n" ) ;
- >else printf( " trad C\n" ) ;
- >}
-
- This is correct, but it is only because 0xFFFFFFFF is too big for an int
- that it becomes an unsigned int. In an implementation with 32-bit ints
- 0x7fff will always be an int.
-
- On a slightly off-topic note I would like to comment on your use of "%d"
- to print the result of the sizeof operator. Since sizeof returns a "size_t"
- the safest way to print it is to use "%lu" and cast the value to (unsigned
- long), or at least in the example above cast it to int. (After all,
- sizeof(long int) is unlikely to be larger than INT_MAX ;-). )
- I am aware that it will (appear to) work on SAS/C and most other (non-msdos)
- systems and that you specified ints to be 32 bits, but you didn't mention
- the size of long ints ;-) (DEC Alpha, anyone?).
-
-
- >> unsigned short, and then immediately convert it back to int. Of course,
- >> the ISO C Standard does give permission for an implementation to carry out
- >> the comparison by any arcane magic it may wish, as long as a conforming
- >> program is not able to tell the difference. (The "as if" rule.)
- >>
- >> (Note furthermore that even though a and b are both unsigned shorts, the
- >> type of the expression (a | b) is int!)
-
- >a and b are promoted to int under ANSI, and hence a | b is int. Trad. C
- >would have promoted a and b to u-int.
-
- Correct again, but I must admit that I don't worry too much about K&R C
- these days. I find C's integer promotion rules plenty complicated without
- having to worry about mixing ANSI and K&R rules ;-).
- (Especially since promotion rules was probably one of the major areas of
- change in the ANSI standard (not counting prototypes, of course).)
-
-
- >Adding unsigned short c ;
- >and setting c = (a | b) before using c in the if changes the SAS
- >behaviour. The implication is that SAS are doing a sign extension of a
- >and b on the int conversion in the if, but not in the assign...
- >now where is that dissassembler...
-
- Oh, I can tell you about the generated code, if you really want to know...
-
- In the original example showing the bug the relevant code looks like this:
-
- | 0010 3E3C FFFF MOVE.W #FFFF,D7
- | 0014 3C3C FFFF MOVE.W #FFFF,D6
- | 0018 3007 MOVE.W D7,D0
- | 001A 8046 OR.W D6,D0
- | 001C 0C40 7FFF CMPI.W #7FFF,D0
- | 0020 6F0C BLE.B 002E
-
- The last instruction (BLE.B) is the culprit. It compares the values as
- words and then does a branch on overflow instead of carry (i.e., a signed
- compare of 16 bit values). When the expression is written as
- if (a > 0x7fff) {
- it correctly generates a BLS.B instruction.
-
- I can understand how it is possible for a bug like that to slip through.
- I find the second bug that I described in the original posting much more
- funny. (A conditional expression in a previous procedure caused the
- compiler to be confused about the constness of things.)
-
-
- --
- Per Liboriussen
- liborius@daimi.aau.dk
-